package com.yihaodian.search.code.util;

import java.io.File;
import java.util.List;

import org.apache.log4j.Logger;
import org.tmatesoft.svn.core.SVNDepth;
import org.tmatesoft.svn.core.SVNException;
import org.tmatesoft.svn.core.SVNURL;
import org.tmatesoft.svn.core.auth.ISVNAuthenticationManager;
import org.tmatesoft.svn.core.internal.io.dav.DAVRepositoryFactory;
import org.tmatesoft.svn.core.internal.io.fs.FSRepositoryFactory;
import org.tmatesoft.svn.core.internal.io.svn.SVNRepositoryFactoryImpl;
import org.tmatesoft.svn.core.internal.wc.DefaultSVNOptions;
import org.tmatesoft.svn.core.wc.SVNClientManager;
import org.tmatesoft.svn.core.wc.SVNInfo;
import org.tmatesoft.svn.core.wc.SVNRevision;
import org.tmatesoft.svn.core.wc.SVNUpdateClient;
import org.tmatesoft.svn.core.wc.SVNWCClient;
import org.tmatesoft.svn.core.wc.SVNWCUtil;

import com.yihaodian.search.code.manage.handler.UpdateEventHandler;
import com.yihaodian.search.code.model.UpdateCodeEntry;

public class SvnUtil {
	static Logger logger = Logger.getLogger(SvnUtil.class);

	private static String username = "zhaowei1";
	private static String password = "wei00";

	public static SVNClientManager authSvn(String username, String password) {
		// 初始化版本库
		setupLibrary();

		// 身份验证
		ISVNAuthenticationManager authManager = SVNWCUtil.createDefaultAuthenticationManager(
				username, password);

		DefaultSVNOptions options = SVNWCUtil.createDefaultOptions(true);
		SVNClientManager clientManager = SVNClientManager.newInstance(options, authManager);
		return clientManager;
	}

	/**
	 * Initializes the library to work with a repository via different
	 * protocols.
	 */
	private static void setupLibrary() {
		// For using over http:// and https://
		DAVRepositoryFactory.setup();

		// For using over svn:// and svn+xxx://
		SVNRepositoryFactoryImpl.setup();

		// For using over file:///
		FSRepositoryFactory.setup();
	}

	public static boolean doCheckOut(File checkOutPath, String svnRepository) {
		SVNClientManager clientManager = SvnUtil.authSvn(username, password);
		SVNUpdateClient client = clientManager.getUpdateClient();
		try {
			SVNURL repositoryBaseUrl = SVNURL.parseURIDecoded(svnRepository);
			client.doCheckout(repositoryBaseUrl, checkOutPath, SVNRevision.HEAD, SVNRevision.HEAD,
					SVNDepth.INFINITY, false);

			client.setIgnoreExternals(true);
		} catch (SVNException e) {
			logger.error(e.getMessage(), e);
			System.out.println(e.getMessage());
			return false;
		}
		
		System.out.println("checkout " + svnRepository);
		return true;
	}

	public static boolean doUpdate(File checkOutPath, boolean needEventHandler, List<UpdateCodeEntry> updateList) {
		SVNClientManager clientManager = SvnUtil.authSvn(username, password);
		SVNUpdateClient client = clientManager.getUpdateClient();
		client.setIgnoreExternals(true);
		UpdateEventHandler updateHandler = null;
		if(needEventHandler){
			updateHandler = new UpdateEventHandler();
			updateHandler.clearUpdateList();
			client.setEventHandler(updateHandler);
		}
		try {
			client.doUpdate(checkOutPath, SVNRevision.HEAD, SVNDepth.INFINITY, true, false);

		} catch (SVNException e) {
			logger.error(e.getMessage(), e);
			System.out.println(e.getMessage());
			return false;
		}
		
		if(needEventHandler)
			updateList.addAll(updateHandler.getUpdateList());

		return true;
	}

	public static SVNInfo getSvnFileInfo(File workingFile) {
		SVNWCClient wcClient = SvnUtil.authSvn(username, password).getWCClient();
		SVNInfo svninfo = null;
		try {
			svninfo = wcClient.doInfo(workingFile, SVNRevision.WORKING);
		} catch (SVNException e) {
			logger.error(e.getMessage(), e);
		}
		if (svninfo != null)
			System.out.println("Author: " + svninfo.getAuthor() + ";\nCommittedDate: "
					+ svninfo.getCommittedDate() + ";\nCommittedRevision: "
					+ svninfo.getCommittedRevision() + ";\nURL: " + svninfo.getURL()
					+ ";\nRepositoryUUID: " + svninfo.getRepositoryUUID());
		return svninfo;
	}

	public static void main(String[] args) {
		// SvnUtil.doCheckOut(new File("E:\\test"),
		// "http://svn.yihaodian.com/svn/source/yihaodian/IT3/branches/804-domain/search-code");
		// SvnUtil.getSvnFileInfo(new File("E:\\test\\pom.xml"));
		SvnUtil.doUpdate(new File("E:\\test"), false, null);
	}
}
